﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace V2TEK.NET.SH.Silverlight.Charts.Core.Schedule
{
    public static class DateTimeHelper
    {
        public static DateTime EnsurePreDate(this DateTime date, DateTimeType type)
        {
            switch (type)
            {
                case DateTimeType.Year:
                    date = new DateTime(date.Year, 1, 1);
                    break;
                case DateTimeType.Quarter:
                    int q = (date.Month + 2) / 3;
                    date = new DateTime(date.Year, (q - 1) * 3 + 1, 1);
                    break;
                case DateTimeType.BigMonth:
                case DateTimeType.Month:
                    date = new DateTime(date.Year, date.Month, 1);
                    break;
                case DateTimeType.Week:
                    int delt = date.Day - (int)date.DayOfWeek;
                    if (delt > 0)
                        date = new DateTime(date.Year, date.Month, delt);
                    else
                        date = new DateTime(date.Year, 1, 1).AddDays(date.DayOfYear - (int)date.DayOfWeek - 1);
                    break;
                case DateTimeType.Day:
                case DateTimeType.WeekDay:
                    date = new DateTime(date.Year, date.Month, date.Day);
                    break;
                case DateTimeType.Hour:
                    date = new DateTime(date.Year, date.Month, date.Day, date.Hour, 0, 0);
                    break;
                case DateTimeType.Minute:
                    date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, 0);
                    break;
                default:
                    break;
            }
            return date;
        }

        /// <summary>
        /// Using Add & Substract function must pre-using EnsurePreDate, esp. DateTimeType is Quarter
        /// </summary>
        /// <param name="type"></param>
        /// <param name="date"></param>
        /// <param name="number"></param>
        /// <returns></returns>
        public static DateTime Add(this DateTime date, DateTimeType type, double number)
        {
            switch (type)
            {
                case DateTimeType.Year:
                    date = date.AddYears(Convert.ToInt32(number));
                    break;
                case DateTimeType.Quarter:
                    date = date.AddMonths(3 * Convert.ToInt32(number));
                    break;
                case DateTimeType.BigMonth:
                case DateTimeType.Month:
                    date = date.AddMonths(Convert.ToInt32(number));
                    break;
                case DateTimeType.Week:
                    date = date.AddDays(7 * number);
                    break;
                case DateTimeType.Day:
                case DateTimeType.WeekDay:
                    date = date.AddDays(number);
                    break;
                case DateTimeType.Hour:
                    date = date.AddHours(number); 
                    break;
                case DateTimeType.Minute:
                    date = date.AddMinutes(number); 
                    break;
                default:
                    date = date.AddMilliseconds(number);
                    break;
            }
            return date;
        }

        public static DateTime Substract(this DateTime date, DateTimeType type, double number)
        {
            switch (type)
            {
                case DateTimeType.Year:
                    date = date.AddYears(-Convert.ToInt32(number));
                    break;
                case DateTimeType.Quarter:
                    date = date.AddMonths(-3 * Convert.ToInt32(number));
                    break;
                case DateTimeType.BigMonth:
                case DateTimeType.Month:
                    date = date.AddMonths(-Convert.ToInt32(number));
                    break;
                case DateTimeType.Week:
                    date = date.AddDays(-7 * number);
                    break;
                case DateTimeType.Day:
                case DateTimeType.WeekDay:
                    date = date.AddDays(-number);
                    break;
                case DateTimeType.Hour:
                    date = date.AddHours(-number);
                    break;
                case DateTimeType.Minute:
                    date = date.AddMinutes(-number);
                    break;
                default:
                    date = date.AddMilliseconds(-number);
                    break;
            }
            return date;
        }


        public static TimeSpan GetDateTimeRange(this DateTime date, DateTimeType type, int range)
        {
            DateTime endDate = date;
            switch (type)
            {
                case DateTimeType.Year:
                    endDate = date.AddYears(range);
                    break;
                case DateTimeType.Quarter:
                    endDate = date.AddMonths(3 * range);
                    break;
                case DateTimeType.BigMonth:
                case DateTimeType.Month:
                    endDate = date.AddMonths(range);
                    break;
                case DateTimeType.Week:
                    return new TimeSpan(range * 7, 0, 0, 0);
                case DateTimeType.Day:
                case DateTimeType.WeekDay:
                    return new TimeSpan(range, 0, 0, 0);
                case DateTimeType.Hour:
                    return new TimeSpan(range, 0, 0);
                case DateTimeType.Minute:
                    return new TimeSpan(0, range, 0);
                default:
                    break;
            }

            return endDate.Subtract(date);
        }

        public static bool IsUnChangeRange(this DateTimeType currentDateTimeType)
        {
            return currentDateTimeType != DateTimeType.BigMonth && currentDateTimeType != DateTimeType.Month && currentDateTimeType != DateTimeType.Year && currentDateTimeType != DateTimeType.Quarter;
        }
    }
}
